package com.zkk.tankgame04;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;

/**
 * 坦克大战的绘图区域
 * */
public class MyPanel extends JPanel implements KeyListener,Runnable {
    //定义我的坦克
    MyTank myTank = null;
    //定义敌人坦克,放入vector(多线程)
    Vector<EnemyTank> enemyTanks = new Vector<>();
    int enemyTanksNum = 3;
    //定义一个存放Node对象的Vector，用于恢复敌人坦克的坐标和方向
    Vector<Node> nodes = new Vector<>();
    //定义一个Vector 用于存放炸弹
    //说明，当子弹击中坦克时，加入一个Bomb对象到bombs
    Vector<Bomb> bombs = new Vector<>();
    //爆炸图片
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    public MyPanel(String Key){
        //判断是否有记录文件 如果有继续执行 没有提示只能开启新游戏，key = "1"
        File file = new File(Recorder.getRecordFile());
        if (file.exists()){
            nodes = Recorder.getNodesAndEnemyTankRec();
        }else {
            System.out.println("文件不存在，只能开启新游戏");
            Key = "1";
        }

        myTank = new MyTank(100,500);//初始化自己的坦克
        //将MyPanel对象的enemyTanks设置给 Recorder的 enemyTanks
        Recorder.setEnemyTanks(enemyTanks);
        switch (Key){
            case "1":
                //初始化敌人坦克
                for(int i = 0;i < enemyTanksNum;i++){
                    EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 100);
                    //将enemyTanks集合设置给enemyTank
                    enemyTank.setEnemyTanks(enemyTanks);
                    enemyTank.setDirect(2);
                    //启动敌人坦克线程
                    new Thread(enemyTank).start();
                    //给敌人坦克初始化加入一颗子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    //加入enemyTank的Vector成员
                    enemyTank.shots.add(shot);
                    //启动shot对象
                    new Thread(shot).start();

                    enemyTanks.add(enemyTank);
                }
                break;
            case "2":
                //初始化敌人坦克
                for(int i = 0;i < nodes.size();i++){
                    Node node = nodes.get(i);
                    EnemyTank enemyTank = new EnemyTank(node.getX(),node.getY() );
                    //将enemyTanks集合设置给enemyTank
                    enemyTank.setEnemyTanks(enemyTanks);
                    enemyTank.setDirect(node.getDirect());
                    //启动敌人坦克线程
                    new Thread(enemyTank).start();
                    //给敌人坦克初始化加入一颗子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    //加入enemyTank的Vector成员
                    enemyTank.shots.add(shot);
                    //启动shot对象
                    new Thread(shot).start();

                    enemyTanks.add(enemyTank);
                }
        }


        myTank.setSpeed(4);
        //加载爆炸效果三张图片
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));

        //播放音乐
        new AePlayWave("src\\111.wav").start();

    }
    //编写方法，在画板上显示显示我方击毁敌方坦克的信息
    public void showInfo(Graphics g){

        //画出玩家的总成绩
        g.setColor(Color.BLACK);
        Font font = new Font("宋体", Font.BOLD, 25);
        g.setFont(font);//给画笔设置字体
        g.drawString("您累积击毁敌方坦克",1020,30);//画字符串
        drawTank(1020,60,g,0,1);//画一个坦克
        g.setColor(Color.BLACK);
        g.drawString(Recorder.getAllEnemyTankNum() + "",1080,100);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        g.fillRect(0,0,1000,750);//填充矩形默认黑色
        showInfo(g);
        //画坦克--封装成方法
                if (myTank != null && myTank.isLive){
                    drawTank(myTank.getX(),myTank.getY(),g,myTank.getDirect(),myTank.getType());
                }

        //画出敌人的坦克 遍历Vector
        for (int i = 0; i < enemyTanks.size(); i++) {
            //取出坦克
            EnemyTank enemyTank = enemyTanks.get(i);
            //
            if (myTank.getShot() != null && enemyTank.isLive){

                drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),enemyTank.getType());
                //画出 enemyTank所有子弹
                for (int j = 0; j < enemyTank.shots.size(); j++) {
                    //取出子弹
                    Shot shot = enemyTank.shots.get(j);
                    //绘制
                    if (shot.isLive){
                        g.draw3DRect(shot.x,shot.y,2,2,false);
                    }else {
                        //从Vector移除
                        enemyTank.shots.remove(shot);
                    }
                }
            }
        }

        //画出MyTank射击的子弹(一颗)
//        if (myTank.getShot() != null && myTank.getShot().isLive == true){
//
//            g.draw3DRect(myTank.getShot().x,myTank.getShot().y,2,2,false);
//        }
        //将mytank的子弹集合 shots,遍历取出绘制
        for (int i = 0; i < myTank.shots.size(); i++) {
            Shot shot = myTank.shots.get(i);
            if (shot != null && shot.isLive){
                g.draw3DRect(shot.x,shot.y,1,1,false);
            }else {//如果该shot对象已经失效，就从集合中移除
                myTank.shots.remove(shot);
            }
        }

        //如果bombs集合中有对象，就画出来
        for (int i = 0; i < bombs.size(); i++) {
            //取出炸弹
            Bomb bomb = bombs.get(i);
            //根据当前这个bomb对象的life值画出对于的图片
            if (bomb.life > 6){
                g.drawImage(image1,bomb.x,bomb.y,60,60,this);
            }else if(bomb.life > 3){
                g.drawImage(image2,bomb.x,bomb.y,60,60,this);
            }else {
                g.drawImage(image3,bomb.x,bomb.y,60,60,this);
            }
            //让这个炸弹的生命值减少
            bomb.lifeDown();
            //如果bomb life值为0， 就从bombs的集合中删除
            if (bomb.life == 0){
                bombs.remove(bomb);
            }
        }


    }

    //画坦克
    /**
     *
     * @param x 坦克的左上角x坐标
     * @param y 坦克的左上角y坐标
     * @param g 画笔
     * @param direct 坦克方向（上下左右）
     * @param type  坦克类型（敌方？ 我方？）
     */
    public void drawTank(int x,int y,Graphics g,int direct,int type){
    //1.根据不同类型的坦克，设置不同的颜色
        switch(type){

            case 0://0:我方坦克
                g.setColor(Color.PINK);
                break;
            case 1://1：敌方坦克
                g.setColor(Color.yellow);
                break;
        }

    //2.根据坦克的初始方向，来绘制坦克
        //direct(0:向上 1：向右 2：向下 3向左 )
        switch(direct){
            case 0://表示向上
                g.fill3DRect(x,y,10,60,false);
                g.fill3DRect(x + 30,y,10,60,false);
                g.fill3DRect(x + 10,y + 10,20,40,false);
                g.fillOval(x + 10,y + 20,20,20);
                g.drawLine(x + 20,y + 30,x + 20,y);
                break;
            case 1://右
                g.fill3DRect(x,y,60,10,false);
                g.fill3DRect(x,y + 30,60,10,false);
                g.fill3DRect(x + 10,y + 10,40,20,false);
                g.fillOval(x + 20,y + 10,20,20);
                g.drawLine(x + 30,y + 20,x + 60,y + 20);
                break;
            case 2://下
                g.fill3DRect(x,y,10,60,false);
                g.fill3DRect(x + 30,y,10,60,false);
                g.fill3DRect(x + 10,y + 10,20,40,false);
                g.fillOval(x + 10,y + 20,20,20);
                g.drawLine(x + 20,y + 30,x + 20,y + 60);
                break;
            case 3:
                g.fill3DRect(x,y,60,10,false);
                g.fill3DRect(x,y + 30,60,10,false);
                g.fill3DRect(x + 10,y + 10,40,20,false);
                g.fillOval(x + 20,y + 10,20,20);
                g.drawLine(x + 30,y + 20,x,y + 20);
                break;
            default:
                System.out.println("暂时无处理....");

        }
    }

    //遍历敌人所有子弹 看看是否打到我方坦克
    public void hitMyTank(){
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            for (int j = 0; j < enemyTank.shots.size(); j++) {
                //取出子弹
                Shot shot = enemyTank.shots.get(j);
                //判断子弹是否与我方坦克碰撞
                if (myTank.isLive && shot.isLive){
                    hitTank(shot,myTank);
                }
            }
        }
    }

    //所有的子弹，都取出和取出所有敌人的坦克，进行判断
    public void hitEnemyTank(){

        //遍历我们的子弹
        for(int j = 0;j < myTank.shots.size();j++){

            Shot shot = myTank.shots.get(j);
            //判断是否击中敌人坦克
            if (shot != null && shot.isLive){//当我的坦克的子弹存活
                //由于不知道会打到哪一个敌方 所以遍历敌方所有坦克
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    hitTank(shot,enemyTank);
                }
            }
        }

    }


    //判断子弹是否击中坦克
    public void hitTank(Shot s,Tank enemyTank){
        //判断s击中坦克-----> 修改子弹 坦克 生命状态
        switch (enemyTank.getDirect()){

            case 0:
            case 2://坦克方向向上或者向下
                if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 40
                    && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 60){
                    s.isLive = false;
                    enemyTank.isLive = false;
                    //字弹击中后 把坦克从容器移除
                    enemyTanks.remove(enemyTank);
                    //当我方击毁一个敌人坦克时 就对allEnemyTankNum++
                    //但由于此方法调用时有可能是敌方击中我方 得进行判断 击中的坦克是否是敌方坦克 是的话在allEnemyTankNum++
                    if (enemyTank instanceof EnemyTank){
                        Recorder.addAllEnemyTankNum();
                    }
                    //创建Bomb对象，加入到bombs集合中去
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(bomb);
                }
                break;

            case 1:
            case 3://坦克方向向左或者向右
                if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 60
                        && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 40){
                    s.isLive = false;
                    enemyTank.isLive = false;
                    enemyTanks.remove(enemyTank);
                    //当我方击毁一个敌人坦克时 就对allEnemyTankNum++
                    //但由于此方法调用时有可能是敌方击中我方 得进行判断 击中的坦克是否是敌方坦克 是的话在allEnemyTankNum++
                    if (enemyTank instanceof EnemyTank){
                        Recorder.addAllEnemyTankNum();
                    }
                    //创建Bomb对象，加入到bombs集合中去
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(bomb);
                }
                break;

        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_W){//上
            //改变方向
            myTank.setDirect(0);
            myTank.moveUp();
        }else if(e.getKeyCode() == KeyEvent.VK_D){//右
            myTank.setDirect(1);
            myTank.moveRight();
        }else if(e.getKeyCode() == KeyEvent.VK_S){//下
            myTank.setDirect(2);
            myTank.moveDown();
        }else if(e.getKeyCode() == KeyEvent.VK_A){//左
            myTank.setDirect(3);
            myTank.moveLeft();
        }
        //如果用户按下的是J就发射
        if (e.getKeyCode() == KeyEvent.VK_J){
            //判断mytank的那颗子弹是否销毁或是否有创建
//            if (myTank.getShot() == null || !myTank.getShot().isLive )
//            myTank.shotEnemyTank();
            myTank.shotEnemyTank();
        }
        //重绘
        this.repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {//每隔100ms,重绘区域, 刷新区域 实现子弹移动可视化效果
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            hitEnemyTank();
            hitMyTank();
            this.repaint();
        }
    }
}
